<?php

namespace catchAdmin\permissions\model;

use catchAdmin\permissions\model\search\UserSearch;
use catcher\base\CatchModel;
use catcher\CatchQuery;
use catcher\exceptions\FailedException;
use catcher\Utils;
use think\db\Query;
use think\Paginator;
use think\facade\Db;
use catchAdmin\permissions\model\Roles;

class Users extends CatchModel
{
    use HasRolesTrait;
    use HasJobsTrait;
    use HasProfessionalTrait;
    use UserSearch;
    use HasDepartmentsTrait;
    use DataRangScopeTrait;

    protected $name = 'users';
    protected $json = ['department_path', 'other_dept'];
    protected $jsonAssoc = true;
    protected $field = [
        'id', //
        'username', // 用户名
        'password', // 用户密码
        'email', // 邮箱 登录
        'avatar', // 头像
        'remember_token',
        'creator_id', // 创建者ID
        'department_id', // 部门ID
        'status', // 用户状态 1 正常 2 禁用
        'last_login_ip', // 最后登录IP
        'last_login_time', // 最后登录时间
        'created_at', // 创建时间
        'updated_at', // 更新时间
        'deleted_at', // 删除状态，0未删除 >0 已删除,
        'doctor_code', //医生编码,
        'good_at', //擅长
        'introduction', //简介,
        'department_path',
        'other_dept'
    ];


    /**
     * set password
     *
     * @time 2019年12月07日
     * @param $value
     * @return false|string
     */
    public function setPasswordAttr($value)
    {
        return password_hash($value, PASSWORD_DEFAULT);
    }

    public function getDoctorCodeAttr($value): string
    {
        return (string)$value;
    }

    /**
     * 用户列表
     *
     * @time 2019年12月08日
     * @return array|\think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function getList()
    {

        $users = $this->dataRange()->withoutField(['updated_at', 'password', 'remember_token'], true)
            ->catchSearch()
            ->catchLeftJoin(Department::class, 'id', 'department_id', ['department_name'])
            ->with(['jobs', 'roles', 'professionals'])
            ->where($this->aliasField('id'), '<>', 1)
            ->order($this->aliasField('id'), 'desc')
            ->paginate()->toArray();

        foreach ($users['data'] as &$user) {
            $user['roles'] = array_column($user['roles'], 'id');
            $user['jobs'] = array_column($user['jobs'], 'id');
            $user['professionals'] = array_column($user['professionals'], 'id');
        }


        return Paginator::make($users['data'], $users['per_page'], $users['current_page'], $users['total']);
    }

    public function getDoctorList()
    {
        return $this->withoutField(['updated_at', 'password', 'remember_token'], true)
            ->catchSearch()
            ->catchLeftJoin(UserHasJobs::class, "uid", "id")
            ->select();
    }

    /**
     * 获取权限
     *
     * @time 2019年12月12日
     * @param $uid
     * @return array
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\db\exception\DataNotFoundException
     */
    public function getPermissionsBy($uid = 0): array
    {
        // 获取超级管理配置 超级管理员全部权限
        if ($uid == config('catch.permissions.super_admin_id')) {
            return Permissions::select()->column('id');
        }

        $roles = $uid ? $this->findBy($uid)->getRoles() : $this->getRoles();

        $permissionIds = [];
        foreach ($roles as $role) {
            $permissionIds = array_merge($permissionIds, $role->getPermissions()->column('id'));
        }

        return array_unique($permissionIds);
    }

    /**
     * 后台根据权限标识判断用户是否拥有某个权限
     * @param string $permission_mark
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * 用法  request()->user()->can('permission@create');
     */
    public function can($permission_mark)
    {
        // 超级管理员直接返回true
        if (Utils::isSuperAdmin()) {
            return true;
        }
        // 查询当前用户的权限
        return in_array(
            Permissions::where('permission_mark', $permission_mark)->value('id') ?: 0,
            $this->getPermissionsBy()
        );
    }

    /**
     *
     * @time 2019年12月08日
     * @return mixed
     */
    public function followRole()
    {
        return $this->belongsToMany(Users::class, 'user_has_roles', 'uid', 'uid');
    }

    /**
     * 获取随访人员
     */
    public function getPersonnel()
    {
        $role_id = (new Roles())->where('identify', 'sfry')->value('id');
        return $this->followRole()
            ->where('role_id', $role_id)
            ->select()
            ->each(function ($item, $key) {
                $item['department_name'] = Department::where('id', $item['department_id'])->value('department_name');
                return $item;
            })
            ->toArray();
    }

    /**
     * 医生端我的信息
     *
     * @time 2019年12月08日
     * @return array|\think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function getYhdDoctor($doctor_code)
    {
        $user = $this->where('doctor_code', $doctor_code)
            ->field('username,doctor_code')
            ->catchLeftJoin(Department::class, 'id', 'department_id', ['department_name'])
            ->catchLeftJoin(UserHasJobs::class, 'uid', 'id', ['job_id'])
            ->find();
        $user['jobs'] = (new Job())->where("id", $user['job_id'])->value("job_name");
        unset($user['job_id']);
        return $user;
    }

    /**
     * 条件获取数据
     * @param array $where
     * @param string $field
     */
    public function getOneData(array $where = [], string $field = "*")
    {
        return $this->where($where)->field($field)->find();
    }

    /**
     * 获取全部数据
     * @param array $where
     * @param string $field
     */
    public function getDatas(array $where = [], string $field = "*")
    {
        return $this->catchSearch()->where($where)->field($field)->select();
    }

    /**
     * 获取全部数据（不加搜索器）
     * @param array $where
     * @param string $field
     */
    public function getConditionData(array $where = [], string $field = "*")
    {
        return $this->where($where)->field($field)->select();
    }

    public function getDoctorListByIds(array $doctorIds): array
    {
        $users = $this->alias("t1")->field(["t1.id", "username", "department_name", "good_at", "introduction", "avatar"], true)
            ->catchSearch()
            ->catchLeftJoin(Department::class, 'id', 'department_id', ['department_name'])
            ->with(['jobs' => function (CatchQuery $query) {
                $query->alias("t2")->field(["t2.job_name", "t2.id"]);
            }, 'professionals'])
            ->where($this->aliasField('id'), 'in', $doctorIds)
            ->order($this->aliasField('id'), 'desc')->select();
        return $users->toArray();
    }

    /**
     * 获取角色人员
     * @param array $where
     */
    public function getRoleUserOne(array $where = [])
    {
        return $this->followRole()->where($where)->find();
    }

    /**
     * 获取当前登陆人科室职称信息
     * @param int $user_id
     */
    public function currentUserDepProInfo(int $user_id)
    {
        return Db::name($this->name)
            ->alias('user')
            ->leftJoin('departments dep', 'user.department_id = dep.id')
            ->leftJoin('user_has_professional has', 'user.id = has.uid')
            ->leftJoin('professional pro', 'has.professional_id = pro.id')
            ->where('user.id', $user_id)
            ->field('user.id,user.username,user.doctor_code,user.avatar,dep.department_name,pro.name')
            ->find();
    }

    public function getAvatarAttr($value, $data): string
    {
        if (!empty($value)) {
            return request()->domain() . $value;
        }
        return "";
    }

    /**
     * 获取登陆人角色信息
     * @param int $user_id
     * @param string $field
     */
    public function currentUserRoleInfo(int $user_id, string $field = "*")
    {
        return Db::name($this->name)
            ->alias('user')
            ->leftJoin('user_has_roles has', 'user.id = has.uid')
            ->leftJoin('roles role', 'has.role_id = role.id')
            ->where('user.id', $user_id)
            ->field($field)
            ->select();
    }
}
